<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------

use think\Db;
// 应用公共文件
//随机生成字符串函数
function GetRandomStr($len=6,$type='mix')
{
    $len = intval($len);
    if($len >90) $len = 90;
    $str = '';
    switch ($type) {
        case 'int':
            $templet = '012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789';
            break;
        case 'lowchar':
            $templet = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl';
            break;
        case 'upchar':
            $templet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL';
            break;
        case 'char':
            $templet = 'abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzamwz0379bhklqdklg482156smyew';
            break;
        case 'chartoupper':
            $templet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZAMWZ0379BHKLQDKLG482156SMYEW';
            break;
        default:
            $templet = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$%^&*()_+-=[]{}:";`/,.?|';
            break;
    }
    $start = mt_rand(1, (90-$len));
    $string = str_shuffle($templet);
    return substr($string,$start,$len);
}

/**
 * md5加密
 */
function CheckMd5($str,$salt=false)
{
    if($salt){
        $key = md5($salt);
        $str = substr($key,0,16).$str.substr($key,16,16);
    }
    return md5($str);
}

/**
 * [PriceBeautify 金额美化]
 * @author   Devil
 * @blog     http://gong.gg/
 * @version  1.0.0
 * @datetime 2018-04-12T16:54:51+0800
 * @param    [float]                  $price   [金额]
 * @param    [mixed]                  $default [默认值]
 */
function PriceBeautify($price = 0, $default = null)
{
    if(empty($price))
    {
        return $default;
    }

    $price = str_replace('.00', '', $price);
    if(strpos($price, '.') !== false)
    {
        if(substr($price, -1) == 0)
        {
            $price = substr($price, 0, -1);
        }
        if(substr($price, -1) == '.')
        {
            $price = substr($price, 0, -1);
        }
    }
    return $price;
}

/**
 * 金额格式化
 * @author   Devil
 * @blog    http://gong.gg/
 * @version 1.0.0
 * @date    2019-02-20
 * @desc    description
 * @param   [float]         $value     [金额]
 * @param   [int]           $decimals  [保留的位数]
 * @param   [string]        $dec_point [保留小数分隔符]
 */
function PriceNumberFormat($value, $decimals = 2, $dec_point = '.')
{
    return number_format((float) $value, $decimals, $dec_point, '');
}

/**
 * 编辑器中内容的静态资源替换
 * @version  0.0.1
 * @datetime 2017-01-22T16:07:58+0800
 * @param    [string]    $content [在这个字符串中查找进行替换]
 * @param    [string]    $type    [操作类型[get读取额你让, add写入内容](编辑/展示传入get,数据写入数据库传入add)]
 * @return   [string]             [正确返回替换后的内容, 则返回原内容]
 */
function ContentStaticReplace($content, $type = 'get')
{
    $attachment_host_path = request()->domain().'/uploads/';
    // 根据类型处理附件地址
    switch($type)
    {
        // 读取内容
        case 'get':
            return str_replace('src="/uploads/', 'src="'.$attachment_host_path, $content);
        break;
    }
}

/**
 * 小程序富文本标签处理
 * @version 1.0.0
 * @date    2020-01-04
 * @desc    description
 * @param   [string]          $content [需要处理的富文本内容]
 */
function ApMiniRichTextContentHandle($content)
{
    // 标签处理，兼容小程序rich-text
    $search = [
        '<img ',
        '<section',
        '/section>',
        '<p style="',
        '<p>',
        '<div>',
        '<table',
        '<tr',
        '<td',
    ];
    $replace = [
        '<img style="max-width:100%;margin:0;padding:0;display:block;" ',
        '<div',
        '/div>',
        '<p style="margin:0;',
        '<p style="margin:0;">',
        '<div style="margin:0;">',
        '<table style="width:100%;margin:0px;border-collapse:collapse;border-color:#ddd;border-style:solid;border-width:0 1px 1px 0;"',
        '<tr style="border-top:1px solid #ddd;"',
        '<td style="margin:0;padding:5px;border-left:1px solid #ddd;"',
    ];
    return str_replace($search, $replace, $content);
}

/**
 * 生成唯一邀请码
 * $user_id 用户id
 */
function GetUserRecommendCode($user_id)
{
    $sourceString = 'E5FCDG3HQA4B1NOPIJ2RSTUV67MWX89KLYZ';
    $code = '';
    while ($user_id > 0) {
        $mod = $user_id % 35;
        $user_id = ($user_id - $mod) / 35;
        $code = $sourceString[$mod] . $code;
    }
    if (strlen($code) < 6)
        $code = str_pad($code, 6, '0', STR_PAD_LEFT);
    return $code;
}

/**
 * 请求身份 [user(用户), techn(技师)] 默认user
 */
function IdentityType()
{
    $str = "user";
    $headers = request()->header();
    if(!empty($headers['identity-type']))
    {
        $str = trim($headers['identity-type']);
    }
    return $str;
}

/**
 * 请求应用 [web, app] 默认web(ios|android|小程序 均为app) 
 */
function ApplicationType()
{
    $str = "web";
    $headers = request()->header();
    if(!empty($headers['application']))
    {
        $str = trim($headers['application']);
    }
    return $str;
}

/**
 * 当前应用平台
 * 请求客户端 [pc, h5, ios, android, alipay, weixin, baidu, toutiao, qq] 默认pc
 */
function ApplicationClientType()
{
    $str = "pc";
    $headers = request()->header();
    if(!empty($headers['application-client-type']))
    {
        $str = trim($headers['application-client-type']);
    }
    return $str;
}

/**
 * 是否微信环境
 * @version 1.0.0
 * @date    2020-08-26
 * @desc    description
 * @return  [boolean] [否false, 是true]
 */
function IsWeixinEnv()
{
    return (!empty($_SERVER['HTTP_USER_AGENT']) && stripos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false);
}


function cmp($a, $b)
{
    if ($a['price'] < $b['price']) {
        return 1;
    } elseif ($a['price'] > $b['price']) {
        return -1;
    } else {
        return 0;
    }
}

function jzl($a, $b)
{
    if ($a['jzl'] < $b['jzl']) {
        return 1;
    } elseif ($a['jzl'] > $b['jzl']) {
        return -1;
    } else {
        return 0;
    }
}
function online($a, $b)
{
    if ($a['online'] < $b['online']) {
        return 1;
    } elseif ($a['online'] > $b['online']) {
        return -1;
    } else {
        return 0;
    }
}

function allmoney($a, $b)
{
    if ($a['all_money'] < $b['all_money']) {
        return 1;
    } elseif ($a['all_money'] > $b['all_money']) {
        return -1;
    } else {
        return 0;
    }
}
function dmp($a, $b)
{
    if ($a['add_time'] < $b['add_time']) {
        return 1;
    } elseif ($a['add_time'] > $b['add_time']) {
        return -1;
    } else {
        return 0;
    }
}

/**
 * 数组无限级树状结构
 * $array 原始数组
 * $parent_id 父级id
 * $parent_name 父级字段名称
 * $children_name 子级名称
 */
function array_tree_structure($array, $parent_id = 0, $parent_name = 'pid', $children_name = 'children')
{
    $list_data = [];
    foreach($array as $key => $value)
    {
        if($value[$parent_name] == $parent_id)
        {
            $value[$children_name] = array_tree_structure($array, $value['id'], $parent_name, $children_name);
            $list_data[] = $value;
        }
    }
    return $list_data;
}

/**
 *curl访问
 */
function http_curl($url,$params=[])
{
    $info=curl_init(); 
    curl_setopt($info,CURLOPT_RETURNTRANSFER,true);
    
    if(!empty($params))
    {
        //判断是否为post
        curl_setopt($info, CURLOPT_POST, 1);//设置为POST方式 
    
        curl_setopt($info, CURLOPT_POSTFIELDS, $params);
    }
    
    curl_setopt($info,CURLOPT_HEADER,0); 
    curl_setopt($info,CURLOPT_NOBODY,0); 
    curl_setopt($info,CURLOPT_SSL_VERIFYPEER, false); 
    curl_setopt($info,CURLOPT_SSL_VERIFYHOST, false); 
    curl_setopt($info,CURLOPT_URL,$url); 
    $output= curl_exec($info); 
    curl_close($info); 
    return $output;
}

/**
 * [GetClientIP 客户端ip地址]
 * @author   Devil
 * @blog     http://gong.gg/
 * @version  0.0.1
 * @datetime 2017-02-09T12:53:13+0800
 * @param    [boolean]        $long [是否将ip转成整数]
 * @return   [string|int]           [ip地址|ip地址整数]
 */
function GetClientIP($long = false)
{
    $onlineip = '';
    if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown'))
    { 
        $onlineip = getenv('HTTP_CLIENT_IP'); 
    } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown'))
    {
        $onlineip = getenv('HTTP_X_FORWARDED_FOR'); 
    } elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown'))
    {
        $onlineip = getenv('REMOTE_ADDR'); 
    } elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown'))
    {
        $onlineip = $_SERVER['REMOTE_ADDR']; 
    } 
    if($long)
    {
        $onlineip = sprintf("%u", ip2long($onlineip));
    }
    return $onlineip;
}

/**
 *阿里云发送短信
 *@param $accessKeyId accessKeyId
 *@param $accessKeySecret accessKeySecret
 *@param $mobile 手机号
 *@param $sign_name 签名
 *@param $template_code 阿里云短信模板
 *@param $template_param 格式为array 发布短信内容根据阿里云模板定义变量内容格式 
 */
function aliyun_send_sms($accessKeyId,$accessKeySecret,$mobile,$sign_name,$template_code,$template_param)
{
    $params = [];
    // fixme 必填: 短信接收号码
    $params["PhoneNumbers"] = $mobile;
    // fixme 必填: 短信签名，应严格按"签名名称"填写，请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/sign
    $params["SignName"] = $sign_name;
    // fixme 必填: 短信模板Code，应严格按"模板CODE"填写, 请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/template
    $params["TemplateCode"] = $template_code;

    // fixme 可选: 设置模板参数, 假如模板中存在变量需要替换则为必填项
    $params['TemplateParam'] = $template_param;

    // fixme 可选: 设置发送短信流水号
    //$params['OutId'] = "12345";

    // fixme 可选: 上行短信扩展码, 扩展码字段控制在7位或以下，无特殊需求用户请忽略此字段
    //$params['SmsUpExtendCode'] = "1234567";
    
    // *** 需用户填写部分结束, 以下代码若无必要无需更改 ***
    if(!empty($params["TemplateParam"]) && is_array($params["TemplateParam"])) {
        $params["TemplateParam"] = json_encode($params["TemplateParam"], JSON_UNESCAPED_UNICODE);
    }

    // 初始化SignatureHelper实例用于设置参数，签名以及发送请求
    $aliyun_sms = new \aliyun_sms\SignatureHelper();
    // 此处可能会抛出异常，注意catch
    $content = $aliyun_sms->request(
        $accessKeyId,
        $accessKeySecret,
        "dysmsapi.aliyuncs.com",
        array_merge($params, [
            "RegionId" => "cn-hangzhou",
            "Action" => "SendSms",
            "Version" => "2017-05-25",
        ])
        // fixme 选填: 启用https
        // ,true
    );
    $content = collection($content)->toArray();
    return $content;
}

/**
 * 交互式语音应答(通知技师接单)
 */
function ivrCall($accessKeyId, $accessKeySecret, $CalledShowNumber, $CalledNumber, $StartCode)
{
    $params = array();
    // *** 需用户填写部分 ***
    // fixme 必填：是否启用https
    $security = false;
    // fixme 必填: 请参阅 https://ak-console.aliyun.com/ 取得您的AK信息
    $accessKeyId = $accessKeyId;
    $accessKeySecret = $accessKeySecret;

    // fixme 必填: 被叫显号
    $params["CalledShowNumber"] = $CalledShowNumber;
    // fixme 必填: 被叫显号
    $params["CalledNumber"] = $CalledNumber;

    // fixme 必填: 呼叫开始时播放的提示音-语音文件Code名称或者Tts模板Code
    $params["StartCode"] = $StartCode;
    // fixme 可选: Tts模板中的变量替换JSON,假如Tts模板中存在变量，则此处必填
    //$params["StartTtsParams"] = array("AckNum" => "123456");

    // fixme 必填: 按键与语音文件ID或tts模板的映射关系
    $menuKeyMaps = array (
        array ( // 按下1键, 播放语音
            "Key" => "1",
            "Code" => "9a9d7222-670f-40b0-a3af.wav"
        ),
        array ( // 按下2键, 播放语音
            "Key" => "2",
            "Code" => "44e3e577-3d3a-418f-932c.wav"
        ),
        array ( // 按下3键, 播放TTS语音
            "Key" => "3",
            "Code" => $StartCode,
            "TtsParams" => array("product"=>"aliyun", "code"=>"123")
        ),
    );
    // fixme 可选: 重复播放次数
    $params["PlayTimes"] = 3;

    // fixme 可选: 等待用户按键超时时间，单位毫秒
    $params["Timeout"] = 3000;

    // fixme 可选: 播放结束时播放的结束提示音,支持语音文件和Tts模板2种方式,但是类型需要与StartCode一致，即前者为Tts类型的，后者也需要是Tts类型的
    //$params["ByeCode"] = "TTS_71400007";

    // fixme 可选: Tts模板变量替换JSON,当ByeCode为Tts时且Tts模板中带变量的情况下此参数必填
    //$params["ByeTtsParams"] = array("product" => "aliyun", "code" => "123");

    // fixme 可选: 预留给调用方使用的ID, 最终会通过在回执消息中将此ID带回给调用方
    // $params["OutId"] = "yourOutId";
    // *** 需用户填写部分结束, 以下代码若无必要无需更改 ***

    if(!empty($params["StartTtsParams"]) && is_array($params["StartTtsParams"])) {
        $params["StartTtsParams"] = json_encode($params["StartTtsParams"], JSON_UNESCAPED_UNICODE);
    }

    if(!empty($params["ByeTtsParams"]) && is_array($params["ByeTtsParams"])) {
        $params["ByeTtsParams"] = json_encode($params["ByeTtsParams"], JSON_UNESCAPED_UNICODE);
    }
    $i = 0;
    foreach($menuKeyMaps as $menuKeyMap) {
        ++$i;
        $params["MenuKeyMap." . $i . ".Key"] = $menuKeyMap["Key"];
        $params["MenuKeyMap." . $i . ".Code"] = $menuKeyMap["Code"];
        if(!empty($menuKeyMap["TtsParams"]) && is_array($menuKeyMap["TtsParams"])) {
            $params["MenuKeyMap." . $i . ".TtsParams"] = json_encode($menuKeyMap["TtsParams"], JSON_UNESCAPED_UNICODE);
        }
    }
    // 初始化SignatureHelper实例用于设置参数，签名以及发送请求
    $helper = new \aliyun_sms\SignatureHelper();
    // 此处可能会抛出异常，注意catch
    $content = $helper->request(
        $accessKeyId,
        $accessKeySecret,
        "dyvmsapi.aliyuncs.com",
        array_merge($params, array(
            "RegionId" => "cn-hangzhou",
            "Action" => "IvrCall",
            "Version" => "2017-05-25",
        )),
        $security
    );
    $content = collection($content)->toArray();
    return $content;
}

/** 
 * 计算两点地理坐标之间的距离 
 * @param  Decimal $longitude1 起点经度 
 * @param  Decimal $latitude1  起点纬度 
 * @param  Decimal $longitude2 终点经度  
 * @param  Decimal $latitude2  终点纬度 
 * @param  Int     $unit       单位 1:米 2:公里 
 * @param  Int     $decimal    精度 保留小数位数 
 * @return Decimal 
 */ 
function getDistance($longitude1, $latitude1, $longitude2, $latitude2, $unit=2, $decimal=2){
 
    $EARTH_RADIUS = 6370.996; // 地球半径系数 
    $PI = 3.1415926; 
 
    $radLat1 = $latitude1 * $PI / 180.0; 
    $radLat2 = $latitude2 * $PI / 180.0; 
 
    $radLng1 = $longitude1 * $PI / 180.0; 
    $radLng2 = $longitude2 * $PI /180.0; 
 
    $a = $radLat1 - $radLat2; 
    $b = $radLng1 - $radLng2; 
 
    $distance = 2 * asin(sqrt(pow(sin($a/2),2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2),2))); 
    $distance = $distance * $EARTH_RADIUS * 1000; 
 
    if($unit==2){ 
        $distance = $distance / 1000; 
    } 
 
    return round($distance, $decimal); 
 
}



//上级数组绑定
function team_get($uid){
    
    if($uid>0){
        
        $list1=db::name('techn')->where('upid',$uid)->column('user_id');
        
        $list2=db::name('user')->where('upid',$uid)->column('id');
        
        $arr=array_merge($list1,$list2);
        if(!empty($arr)){
            $arr=array_unique($arr);
        }
        $user_bd=db::name('user_bd')->where('user_id',$uid)->select();
        
        $insert=[];
        
        $del=[];
        
        if(!empty($arr)){
            
            if(!empty($user_bd)){
                
                foreach ($user_bd as $k=>$v){
                    if(in_array($v['bduid'],$arr)){
                        $key=array_keys($arr,$v['bduid'])[0];
                        unset($arr[$key]);
                    }else{
                        $del[]=$v['id'];
                    }
                }
                
            }
            
            foreach ($arr as $k=>$v){
                $insertarr=[];
                
                $insertarr['user_id']=$uid;
                
                $insertarr['bduid']=$v;
                
                $insert[]=$insertarr;
            }
            
            if(!empty($insert)){
                db::name('user_bd')->insertAll($insert);
            }
            if(!empty($del)){
                db::name('user_bd')->where('id','in',$del)->delete();
            }
            
        }else{
            db::name('user_bd')->where('user_id',$uid)->delete();
        }
        
    }
    
    
}

//下级数组更新
    function team_get2($uid){
        if($uid>0){
        $list1=db::name('techn')->where('user_id',$uid)->where('upid','>',0)->column('upid');
        
        $list2=db::name('user')->where('id',$uid)->where('upid','>',0)->column('upid');
        
        $arr=array_merge($list1,$list2);
        if(!empty($arr)){
            $arr=array_unique($arr);
        }
        $user_bd=db::name('user_bd')->where('bduid',$uid)->select();
        
        // print_r($user_bd);
        
        // $key=array_keys($arr,'976');
        // print_r($key);
        // exit;
        $insert=[];
        
        $del=[];
        
        if(!empty($arr)){
            
            if(!empty($user_bd)){
                
                foreach ($user_bd as $k=>$v){
                    if(in_array($v['user_id'],$arr)){
                        $key=array_keys($arr,$v['user_id'])[0];
                        unset($arr[$key]);
                    }else{
                        $del[]=$v['id'];
                    }
                }
                
            }
            
            foreach ($arr as $k=>$v){
                $insertarr=[];
                
                $insertarr['bduid']=$uid;
                
                $insertarr['user_id']=$v;
                
                $insert[]=$insertarr;
            }
            
            if(!empty($insert)){
                db::name('user_bd')->insertAll($insert);
            }
            if(!empty($del)){
                db::name('user_bd')->where('id','in',$del)->delete();
            }
            
        }else{
            db::name('user_bd')->where('bduid',$uid)->delete();
        }
        
        
        
        }
    }


function curl_get_contents($url,$timeout=30) {
    $curlHandle = curl_init();
    curl_setopt( $curlHandle , CURLOPT_URL, $url );
    curl_setopt( $curlHandle , CURLOPT_RETURNTRANSFER, 1 );
    curl_setopt( $curlHandle , CURLOPT_TIMEOUT, $timeout );
    curl_setopt($curlHandle, CURLOPT_SSL_VERIFYPEER, FALSE);   //屏蔽ssl证书和host
    curl_setopt($curlHandle, CURLOPT_SSL_VERIFYHOST, FALSE);
    $result = curl_exec( $curlHandle );
    curl_close( $curlHandle );
    return $result;
}

/*
 * 生成随机字符串
 */
function randStr($len=16) {
    $chars='ABDEFGHJKLMNPQRSTVWXYabdefghijkmnpqrstvwxy23456789'; // characters to build the password from
    mt_srand((double)microtime()*1000000*getmypid()); // seed the random number generater (must be done)
    $password='';
    while(strlen($password)<$len)
        $password.=substr($chars,(mt_rand()%strlen($chars)),1);
    return $password;
}


function encrypt_sm2($str, $publickey)
{
    $sm2 = new app\Rtgm\sm\RtSm2();
    $m2EncryptData = $sm2 ->doEncrypt($str, $publickey);
    return $m2EncryptData;
}

function decrypt_sm2($m2EncryptData, $privatekey)
{
    $sm2 = new app\Rtgm\sm\RtSm2();
    $m2DecryptData = $sm2 ->doDecrypt($m2EncryptData, $privatekey);
    return $m2DecryptData;
}

function sign_sm2($document, $privatekey)
{
    $sm2 = new \Rtgm\sm\RtSm2('base64');
    return $sm2 ->doSign($document, $privatekey);
}

function verify_sign_sm2($document, $sign, $publickey)
{
    $sm2 = new \Rtgm\sm\RtSm2('base64');
    return $sm2 ->verifySign($document, $sign, $publickey);
}
